package com.zjzaki.thingsboard.activity.main;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.Switch;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.zjzaki.thingsboard.R;
import com.zjzaki.thingsboard.dao.ThingsBoardDao;
import com.zjzaki.thingsboard.entity.LoginMsg;
import com.zjzaki.thingsboard.ui.CreationChart;
import com.zjzaki.thingsboard.util.FileHelper;
import com.zjzaki.thingsboard.util.IPUtil;
import com.zjzaki.thingsboard.util.JWebSocketClient;

import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class DeviceInfoActivity extends AppCompatActivity {

    //总开关
    @SuppressLint("UseSwitchCompatOrMaterialCode")
    private Switch aSwitch;
    //设备ID
    private String deviceId = "";
    //设备名
    private String deviceName = "";
    //标题栏
    private Toolbar toolbar;
    //动作按钮
    ActionBar supportActionBar;
    //文字页面
    private TextView textView;
    //token值
    private String token;
    //日志提示信息
    private String TAG = "deviceInfo";
    //服务器ip地址
    private String ip = IPUtil.IP;
    //WebSocket
    private JWebSocketClient client;
    //WebSocket信息展示
    private TextView txt_msg;
    /**
     * 折线图显示
     */
    private LineChart lineChart;
    /**
     * 折线图数据列表
     */
    private List<Entry> list;
    /**
     * 折线图数据集合
     */
    private LineDataSet lineDataSet;
    /**
     * 折线图数据
     */
    private LineData lineData;
    /**
     * 封装的折线图
     */
    private CreationChart creationChart;

    /**
     * 进入查看历史数据界面的按钮
     */
    private ImageButton btn_lssj;

    /**
     * 页面创建时执行
     *
     * @param savedInstanceState
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置界面
        setContentView(R.layout.device_info_view);
        //得到token值
        token = new FileHelper(this).getLoginMsg("login.txt").getToken();
        //得到设备id
        deviceId = getIntent().getStringExtra("deviceId");
        //得到设备名称
        deviceName = getIntent().getStringExtra("deviceName");

        toolbar = findViewById(R.id.toolbar2);
        //设置标题栏
        setSupportActionBar(toolbar);
        supportActionBar = getSupportActionBar();
        //设置返回键可见
        supportActionBar.setDisplayHomeAsUpEnabled(true);
        //设置标题
        supportActionBar.setTitle(deviceName);
        //设置设备id显示
        textView = findViewById(R.id.txt_device_info_name);
        //设置设备ID
        textView.setText("设备ID：" + deviceId);
        //得到主开关控件
        aSwitch = findViewById(R.id.swi_main);
        //初始化主开关
        initMainSwitch();
        //初始化信息展示栏
        txt_msg = findViewById(R.id.txt_msg);
        //初始化折线图
        initLineChart();

        //==================================功能选择区=====================================
        //初始化进入历史数据界面的按钮
        btn_lssj = findViewById(R.id.btn_lssj);

        //==================================监听设置======================================
        //设置总开关的监听
        aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    setMainSwitch(true);
                    aSwitch.setChecked(true);
                } else {
                    setMainSwitch(false);
                    aSwitch.setChecked(false);
                }
            }
        });
        //设置功能区历史数据查询的事件监听
        btn_lssj.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //断开webSocket连接
                closeConnect();
                System.out.println("点击了查询历史数据按钮");
                // 跳转
                Intent deviceIntent = new Intent(DeviceInfoActivity.this, HistoricalDataActivity.class);
                // 设置设备id，将设备id传到新界面
                deviceIntent.putExtra("deviceId", deviceId);
                //将设备名，传入到新界面
                deviceIntent.putExtra("deviceName", deviceName);
                //跳转到新界面
                startActivity(deviceIntent);
            }
        });
    }

    /**
     * 初始化折线图
     */
    private void initLineChart() {
        //得到折线图组件
        lineChart = findViewById(R.id.lineChart1);
        //初始化封装的折线图
        creationChart = new CreationChart(lineChart);
        //调用封装的折线图的初始化方法
        creationChart.init();
    }

    /**
     * 初始化得到主按钮状态，并且设置,如果没有则添加一个属性
     */
    private void initMainSwitch() {

        // 是否含有是属性，{"os":"1"} 总开关开，{"cs":"0"}
        boolean isOsHave = false;
        boolean isCsHave = false;
        //String value = 0 + "";
        boolean statusSwitch = false;
        String scope = ThingsBoardDao.getScope(token, deviceId);

        JSONArray scopeJsonArray = JSONObject.parseArray(scope);
        //遍历序列
        for (int i = 0; i < scopeJsonArray.size(); i++) {
            JSONObject scopeJson = (JSONObject) scopeJsonArray.get(i);
            String mainSwitch = scopeJson.getString("key");
            if ("os".equals(mainSwitch) && "1".equals(scopeJson.getString("value"))) {
                isOsHave = true;
                //value = scopeJson.getString("value");
                statusSwitch = true;
                break;
            }
            if ("cs".equals(mainSwitch) && "0".equals(scopeJson.getString("value"))) {
                isCsHave = false;
                statusSwitch = false;
                break;
            }
        }

        if (isOsHave || isCsHave) {
            aSwitch.setChecked(statusSwitch);
        } else {
            if (!isOsHave) {
                ThingsBoardDao.updateScope(token, "os", "1", deviceId);
                aSwitch.setChecked(true);
            }
            if (!isCsHave) {
                ThingsBoardDao.updateScope(token, "cs", "0", deviceId);
                aSwitch.setChecked(false);
            }

        }
    }

    /**
     * 上传总开关的值
     */
    private void setMainSwitch(boolean b) {
        //得到scope的值
        //String scope = ThingsBoardDao.getScope(token, deviceId);
        if (b) {
            ThingsBoardDao.updateScope(token, "os", "1", deviceId);
        } else {
            ThingsBoardDao.updateScope(token, "cs", "0", deviceId);
        }
    }

    /**
     * 返回键状态监听
     *
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

    //========================================webSocket相关==========================================
    /**
     * 断线重连
     */
    @Override
    protected void onResume() {
        super.onResume();

        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
        if (client == null) {
            Log.e(TAG, "``````````````````````onResume");
            initWebSocket();
        } else if (!client.isOpen()) {
            reconnectWs();//进入页面发现断开开启重连
        }
    }

    /**
     * 停止连接
     */
    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "``````````````````````````````onStop");
    }

    /**
     * 销毁连接
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "`````````````````````````onDestroy");
        closeConnect();
    }

    /**
     * 初始化websocket
     */
    public void initWebSocket() {
//        Log.e(TAG, "websocket的地址是：we://" + SpUtils.decodeString("websocketurl"));
        Log.e(TAG, "websocket的地址是：ws://" + ip + ":8080");

        //读取文件获得token
        FileHelper fileHelper = new FileHelper(this);
        LoginMsg loginMsg = fileHelper.getLoginMsg("login.txt");

        String token = loginMsg.getToken();

        URI uri = URI.create("ws://" + ip + ":8080" + "/api/ws/plugins/telemetry?token=" + token);
        // 创建websocket
        client = new JWebSocketClient(uri) {
            @Override
            public void onMessage(String message) {
                super.onMessage(message);
                if (!message.equals("Heartbeat")) {

                    Log.i(TAG, "websocket收到消息：" + message);
                    txt_msg.setText(message);
                    JSONObject tempJson = JSONObject.parseObject(message);
                    JSONObject msgJson = tempJson.getJSONObject("data");
                    JSONArray str = msgJson.getJSONArray("temp");

                    List<Object> objList = null;
                    long time = 0;
                    float temp = 0;
                    if (str.size() != 0) {
                        for (int i = 0; i < str.size(); i++) {
                            objList = (List<Object>) str.get(i);
                        }
                        time = Long.parseLong(objList.get(0).toString());
                        //得到当前的时间的时间戳
                        long time1 = new Date().getTime();
                        //判断当前的数据是不是最新的实时数据
                        if(time1 - 500 < time){
                            temp = Float.parseFloat(objList.get(1).toString());
                            System.out.println(time + "  " + temp);
                            creationChart.addData(time, temp);
                        }
                    }
                }
            }

            @Override
            public void onOpen(ServerHandshake handshakedata) {
                String msg = "{\"tsSubCmds\": [" +
                        " {" +
                        " \"entityType\": \"DEVICE\"," +
                        " \"entityId\": \"" + deviceId + "\"," +
                        " \"scope\": \"LATEST_TELEMETRY\"," +
                        " \"cmdId\": 10" +
                        " }" +
                        " ]," +
                        " \"historyCmds\": []," +
                        " \"attrSubCmds\": []}";

                System.out.println(msg);
                //发送订阅消息
                client.send(msg);
                super.onOpen(handshakedata);

                Log.i(TAG, "websocket连接成功");
            }

            @Override
            public void onError(Exception ex) {
                super.onError(ex);

                Log.i(TAG, "websocket连接错误：" + ex);
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                super.onClose(code, reason, remote);
                if (code != 1000) {
                    reconnectWs();//意外断开马上重连
                }
                Log.i(TAG, "websocket断开连接：·code:" + code + "·reason:" + reason + "·remote:" + remote);
            }
        };
        // 设置超时时间
        client.setConnectionLostTimeout(110 * 1000);
        // 连接websocket
        new Thread() {
            @Override
            public void run() {
                try {
                    //connectBlocking多出一个等待操作，会先连接再发送，否则未连接发送会报错
                    client.connectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 发送消息
     *
     * @param msg
     */
    public void sendMsg(String msg) {
        if (null != client) {
            Log.e("", "^_^Websocket发送的消息：-----------------------------------^_^" + msg);
            if (client.isOpen()) {
                client.send(msg);
            }
        }
    }

    /**
     * 开启重连
     */
    private void reconnectWs() {
        mHandler.removeCallbacks(heartBeatRunnable);
        new Thread() {
            @Override
            public void run() {
                try {
                    Log.e("开启重连", "");
                    client.reconnectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 断开连接
     */
    private void closeConnect() {
        try {
            //关闭websocket
            if (null != client) {
                client.close();
            }
            //停止心跳
            if (mHandler != null) {
                mHandler.removeCallbacksAndMessages(null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client = null;
        }
    }

    //    -------------------------------------websocket心跳检测------------------------------------------------
    private static final long HEART_BEAT_RATE = 10 * 1000;//每隔10秒进行一次对长连接的心跳检测
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (client != null) {
                if (client.isClosed()) {
//                    Log.e("心跳包检测websocket连接状态1", client.isOpen() + "/" + SpUtils.decodeString("websocketurl"));
                    Log.e("心跳包检测websocket连接状态1", client.isOpen() + "/" + ip + ":8080");
                    reconnectWs();//心跳机制发现断开开启重连
                } else {
//                    Log.e("心跳包检测websocket连接状态2", client.isOpen() + "/" + SpUtils.decodeString("websocketurl"));
                    Log.e("心跳包检测websocket连接状态2", client.isOpen() + "/" + ip + ":8080");
//                    sendMsg("Heartbeat");
                }
            } else {
                Log.e("心跳包检测websocket连接状态重新连接", "");
                //如果client已为空，重新初始化连接
                client = null;
//                initSocketClient();
                initWebSocket();
            }
            //每隔一定的时间，对长连接进行一次心跳检测
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };
}
